package com.yfl.logistics.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.yfl.logistics.shiro.CustomRealm;
import com.yfl.logistics.shiro.MyFormAuthenticationFilter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Properties;

//shiro框架配置文件
@Configuration
public class ShiroConfig {

    //配置shiro方言
    @Bean
    public ShiroDialect shiroDialect() {

        return new ShiroDialect();
    }

    //配置核心过滤器工厂

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        //配置验证失败跳转的页面
        shiroFilterFactoryBean.setLoginUrl("/admin/login");
        //配置验证成功的跳转页面
        shiroFilterFactoryBean.setSuccessUrl("/index");

        /*配置放行的匿名过滤器*/
        HashMap<String, String> filterChainDefinitionMap = new HashMap<>();

        filterChainDefinitionMap.put("/h-ui/**", "anon");
        filterChainDefinitionMap.put("/h-ui.admin/**", "anon");
        filterChainDefinitionMap.put("/lib/**", "anon");
        filterChainDefinitionMap.put("/admin/loginPage", "anon");

        //配置退出认证过滤器
        filterChainDefinitionMap.put("/logout", "logout");

        /*配置匿名表单过滤器*/
        filterChainDefinitionMap.put("/**", "authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        /*配置核心安全管理器*/
        shiroFilterFactoryBean.setSecurityManager(securityManager());


        //配置自定义过滤器
        HashMap<String, Filter> filterMape = new HashMap<>();
        filterMape.put("logout", logoutFilter());
        //配置自定义表单认证过滤器
        filterMape.put("authc", new MyFormAuthenticationFilter());

        shiroFilterFactoryBean.setFilters(filterMape);

        return shiroFilterFactoryBean;
    }


    /*配置核心安全管理器*/
    @Bean
    public DefaultWebSecurityManager securityManager() {

        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

        securityManager.setRealm(customRealm());
        //配置缓存管理器
        securityManager.setCacheManager(cacheManager());
        return securityManager;
    }

    //配置Realm使用的缓存管理器
    @Bean
    public CacheManager cacheManager(){
        EhCacheManager ehCacheManager = new EhCacheManager();
        return ehCacheManager;
    }
    //配置自定义退出过滤器
    public LogoutFilter logoutFilter() {

        LogoutFilter logoutFilter = new LogoutFilter();

        logoutFilter.setRedirectUrl("/admin/loginPage");

        return logoutFilter;
    }

    //配置自定义Realm
    @Bean
    public CustomRealm customRealm() {

        CustomRealm customRealm = new CustomRealm();

        //配置凭证匹配器
        customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return customRealm;
    }



    //凭证匹配器

    public HashedCredentialsMatcher hashedCredentialsMatcher() {

        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();

        hashedCredentialsMatcher.setHashIterations(3);
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");

        return hashedCredentialsMatcher;
    }

    //开启shiro支持注解配置
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {

        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }

    //设置Spring框架支持shiro注解配置
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {

        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;

    }

    //创建对springgmvc抛出异常解析器
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver(){
        Properties properties = new Properties();
        properties.put("org.apache.shiro.authz.UnauthorizedException","unauthorized");

        SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
        simpleMappingExceptionResolver.setExceptionMappings(properties);
        return  simpleMappingExceptionResolver;
    }
}
